package com.moyun.modelclass.activity;

import android.annotation.SuppressLint;
import android.content.ContentResolver;
import android.content.ContentValues;
import android.content.Context;
import android.content.Intent;
import android.graphics.Bitmap;
import android.net.Uri;
import android.opengl.GLException;
import android.os.Build;
import android.os.Bundle;
import android.os.Environment;
import android.provider.MediaStore;
import android.util.Log;
import android.view.View;
import android.widget.ImageView;
import android.widget.RelativeLayout;
import android.widget.TextView;

import androidx.core.content.FileProvider;

import com.blankj.utilcode.util.ClickUtils;
import com.hjq.http.EasyHttp;
import com.hjq.http.listener.HttpCallback;
import com.hjq.http.listener.OnDownloadListener;
import com.hjq.http.model.FileContentResolver;
import com.hjq.http.model.HttpMethod;
import com.moyun.modelclass.base.BaseModelActivity;
import com.moyun.modelclass.http.CommonConfiguration;
import com.moyun.modelclass.R;
import com.moyun.modelclass.http.api.RelateThumbnailApi;
import com.moyun.modelclass.http.api.UpdateImageApi;
import com.moyun.modelclass.http.model.HttpData;
import com.moyun.modelclass.utils.ContentResolverUriStore;
import com.moyun.modelclass.utils.FileNewUtils;
import com.moyun.modelclass.utils.StatusBarUtil;
import com.moyun.modelclass.view.gifshow.widget.stlview.callback.OnReadCallBack;
import com.moyun.modelclass.view.gifshow.widget.stlview.widget.STLView;
import com.moyun.modelclass.view.gifshow.widget.stlview.widget.STLViewBuilder;
import com.moyun.modelclass.view.preview.ThumbnailUtils;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.OutputStream;
import java.io.Serializable;
import java.nio.IntBuffer;
import java.security.Key;
import java.util.ArrayList;
import java.util.List;
import java.util.UUID;

import javax.crypto.Cipher;
import javax.crypto.CipherInputStream;
import javax.crypto.spec.SecretKeySpec;
import javax.microedition.khronos.opengles.GL10;

/**
 * 作者：Meteor
 * 日期：2022/1/15 17:25
 * tip：模型详情
 */
public class ModelShowActivity extends BaseModelActivity {
    private RelativeLayout rlModelShowTop;
    private ImageView ivModelShowBack;
    private STLView stlModelShow;
    private TextView tvModelShowXzy;
    private TextView tvModelShowRemark;
    private String mFileId = "";//模型id
    private String mFilePath = "";//模型
    private List<Integer> mXyz = new ArrayList<>();//长宽高，单位是mm
    private String mRemark = "";//注意事项
    private boolean mNeedReGetThumbnail = false;//是否重新获取模型预览图

    public static void start(Context context, String fileId, String filePath, List<Integer> xyz, String remark,boolean needReGetThumbnail) {
        Intent starter = new Intent(context, ModelShowActivity.class);
        starter.putExtra("fileId", fileId);
        starter.putExtra("filePath", filePath);
        starter.putExtra("xyz", (Serializable) xyz);
        starter.putExtra("remark", remark);
        starter.putExtra("needReGetThumbnail", needReGetThumbnail);
        context.startActivity(starter);
    }

    @Override
    protected int getLayoutResId() {
        return R.layout.activity_model_show;
    }

    @Override
    protected void assignViews() {
        rlModelShowTop = (RelativeLayout) findViewById(R.id.rl_model_show_top);
        ivModelShowBack = (ImageView) findViewById(R.id.iv_model_show_back);
        stlModelShow = (STLView) findViewById(R.id.stl_model_show);
        tvModelShowXzy = (TextView) findViewById(R.id.tv_model_show_xzy);
        tvModelShowRemark = (TextView) findViewById(R.id.tv_model_show_remark);

        StatusBarUtil.setPaddingSmart(this, rlModelShowTop);
    }

    @Override
    protected void registerListeners() {
        ClickUtils.applySingleDebouncing(ivModelShowBack, new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                finish();
            }
        });
    }

    @SuppressLint("SetTextI18n")
    @Override
    protected void getExtras(Bundle bundle) {
        mFileId = bundle.getString("fileId", "");
        mFilePath = bundle.getString("filePath", "");
        mXyz = (List<Integer>) bundle.get("xyz");
        mRemark = bundle.getString("remark", "");
        mNeedReGetThumbnail = bundle.getBoolean("needReGetThumbnail",false);

        StringBuilder size = new StringBuilder();
        if (mXyz != null && mXyz.size() > 0) {
            for (int i = 0; i < mXyz.size(); i++) {
                //证明是最后一个
                if (i == mXyz.size() - 1) {
                    size.append(mXyz.get(i)).append("mm");
                } else {
                    size.append(mXyz.get(i)).append("mm*");
                }
            }
        }
        tvModelShowXzy.setText("模型长宽高：" + size);
        tvModelShowRemark.setText("注意：" + mRemark);
    }

    @Override
    protected boolean isRegisterEventBus() {
        return false;
    }

    @Override
    protected void doAction() {
        showProgressDialog();
        downloadFile(mFilePath);
    }

    private void downloadFile(String fileString) {
        File file;
        String fileName = UUID.randomUUID() + ".mystl";
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
            // 适配 Android 10 分区存储特性
            ContentValues values = new ContentValues();
            // 设置显示的文件名
            values.put(MediaStore.Downloads.DISPLAY_NAME, fileName);
            // 生成一个新的 uri 路径
            // 注意这里使用 ContentResolver 插入的时候都会生成新的 Uri
            // 解决方式将 ContentValues 和 Uri 作为 key 和 value 进行持久化关联
            // outputUri = getContentResolver().insert(MediaStore.Downloads.EXTERNAL_CONTENT_URI, values);
            Uri outputUri = ContentResolverUriStore.insert(this, MediaStore.Downloads.EXTERNAL_CONTENT_URI, values);
            file = new FileContentResolver(getContentResolver(), outputUri, fileName);
        } else {
            file = new File(Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS), fileName);
        }

        EasyHttp.download(this)
                .method(HttpMethod.GET)
                .file(file)
                .url(CommonConfiguration.splitResStl(fileString))
                .listener(new OnDownloadListener() {

                    @Override
                    public void onStart(File file) {
                        Log.e("EasyHttp-download==>", "onStart");
                    }

                    @Override
                    public void onProgress(File file, int progress) {
                        Log.e("EasyHttp-download==>", "onProgress");
                    }

                    @Override
                    public void onComplete(File file) {
                        Log.e("EasyHttp-download==>", "onComplete");

                        convertedStl(file);
                    }

                    @Override
                    public void onError(File file, Exception e) {
                        Log.e("EasyHttp-download==>", "onError");
                        file.delete();
                    }

                    @Override
                    public void onEnd(File file) {
                        Log.e("EasyHttp-download==>", "onEnd");
                    }
                })
                .start();
    }

    private void convertedStl(File downloadedFile) {
        //File转换为Uri
        Uri uriOne;
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
            if (downloadedFile instanceof FileContentResolver) {
                uriOne = ((FileContentResolver) downloadedFile).getContentUri();
            } else {
                uriOne = FileProvider.getUriForFile(this, getPackageName() + ".provider", downloadedFile);
            }
        } else {
            uriOne = Uri.fromFile(downloadedFile);
        }


        //解密转换文件
        try {
            ContentResolver contentResolver = getContentResolver();
            FileInputStream inputStream = (FileInputStream) contentResolver.openInputStream(uriOne);
            decrypt(inputStream, CommonConfiguration.mSecretKey);
        } catch (FileNotFoundException e) {
            throw new RuntimeException(e);
        }
    }

    public void decrypt(FileInputStream inputStream, String secretKey) {
        OutputStream outputStream = null;
        try {
            Key key = new SecretKeySpec(secretKey.getBytes(), "AES");
            Cipher cipher = Cipher.getInstance("AES");
            cipher.init(Cipher.DECRYPT_MODE, key);
            CipherInputStream cipherInputStream = new CipherInputStream(inputStream, cipher);

            if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.Q) {
                ContentValues contentValues = new ContentValues();
                contentValues.put(MediaStore.Downloads.DISPLAY_NAME, UUID.randomUUID() + ".stl");
                contentValues.put(MediaStore.Downloads.MIME_TYPE, "application/octet-stream");
                contentValues.put(MediaStore.Downloads.IS_PENDING, 1);

                ContentResolver resolver = getContentResolver();
                Uri uriTwo = resolver.insert(MediaStore.Downloads.EXTERNAL_CONTENT_URI, contentValues);

                outputStream = resolver.openOutputStream(uriTwo);
                if (outputStream != null) {
                    byte[] buffer = new byte[1024];
                    int bytesRead;
                    while ((bytesRead = cipherInputStream.read(buffer)) != -1) {
                        outputStream.write(buffer, 0, bytesRead);
                    }

                    outputStream.close();
                    contentValues.clear();
                    contentValues.put(MediaStore.Downloads.IS_PENDING, 0);
                    resolver.update(uriTwo, contentValues, null, null);
                }
                String filePath = FileNewUtils.getFilePathFromContentUri(this, uriTwo);

                STLViewBuilder.init(stlModelShow).File(new File(filePath)).build();
                stlModelShow.setScale(true);
                stlModelShow.setRotate(true);
                stlModelShow.setVisibility(View.VISIBLE);
                stlModelShow.setOnReadCallBack(new OnReadCallBack() {
                    @Override
                    public void onStart() {

                    }

                    @Override
                    public void onReading(int cur, int total) {

                    }

                    @Override
                    public void onCreateBitmap(GL10 gl, int mOutputWidth, int mOutputHeight) {
                        if (mNeedReGetThumbnail){
                            uploadModelThumbnail(gl, mOutputWidth, mOutputHeight);
                        }
                    }

                    @Override
                    public void onFinish() {

                    }
                });
                dismissProgressDialog();
            }
        } catch (Exception ex) {
            dismissProgressDialog();
            ex.printStackTrace();
        } finally {
            dismissProgressDialog();
            if (outputStream != null) {
                try {
                    outputStream.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }

    private void uploadModelThumbnail(GL10 gl, int mOutputWidth, int mOutputHeight) {
        Bitmap bitmap = createBitmapFromGLSurface(0, 0, mOutputWidth, mOutputHeight, gl);
        File thumbnailFile = ThumbnailUtils.saveBitmapToFile(ModelShowActivity.this, bitmap); // 将缩略图保存到文件
        EasyHttp.post(ModelShowActivity.this).api(new UpdateImageApi()
                        .setFileName(UUID.randomUUID() + ".jpg")
                        .setFile(thumbnailFile)
                        .setWatermark(true))
                .request(new HttpCallback<HttpData<UpdateImageApi.Bean>>(ModelShowActivity.this) {
                    @Override
                    public void onSucceed(HttpData<UpdateImageApi.Bean> imageResult) {
                        if (CommonConfiguration.isLogin(kv)){
                            EasyHttp.post(ModelShowActivity.this).api(new RelateThumbnailApi()
                                            .setThumbnail(imageResult.getData().getUrl())
                                            .setFileId(mFileId))
                                    .request(new HttpCallback<HttpData<UpdateImageApi.Bean>>(this) {
                                        @Override
                                        public void onSucceed(HttpData<UpdateImageApi.Bean> result) {
                                        }
                                    });
                        }
                    }
                });
    }

    private Bitmap createBitmapFromGLSurface(int x, int y, int w, int h, GL10 gl) {
        int bitmapBuffer[] = new int[w * h];
        int bitmapSource[] = new int[w * h];
        IntBuffer intBuffer = IntBuffer.wrap(bitmapBuffer);
        intBuffer.position(0);
        try {
            gl.glReadPixels(x, y, w, h, GL10.GL_RGBA, GL10.GL_UNSIGNED_BYTE,
                    intBuffer);
            int offset1, offset2;
            for (int i = 0; i < h; i++) {
                offset1 = i * w;
                offset2 = (h - i - 1) * w;
                for (int j = 0; j < w; j++) {
                    int texturePixel = bitmapBuffer[offset1 + j];
                    int blue = (texturePixel >> 16) & 0xff;
                    int red = (texturePixel << 16) & 0x00ff0000;
                    int pixel = (texturePixel & 0xff00ff00) | red | blue;
                    bitmapSource[offset2 + j] = pixel;
                }
            }
        } catch (GLException e) {
            return null;
        }
        return Bitmap.createBitmap(bitmapSource, w, h, Bitmap.Config.ARGB_8888);
    }

    @Override
    protected void onRestart() {
        super.onRestart();
        stlModelShow.setVisibility(View.VISIBLE);
        stlModelShow.requestRedraw();
    }

    @Override
    protected void onStop() {
        super.onStop();
        stlModelShow.setVisibility(View.GONE);
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        deleteAllFiles();
    }

    private void deleteAllFiles() {
        File directory = new File("/storage/emulated/0/Download");
        if (directory.exists() && directory.isDirectory()) {
            String[] children = directory.list();
            if (children != null) {
                for (String child : children) {
                    File file = new File(directory, child);
                    file.delete();
                }
            }
        }
    }

}
